`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/03/12 09:54:28
// Design Name: 
// Module Name: rgmii_to_gmii
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module rgmii_to_gmii(
    // PHY芯片传过来的RGMII信号
    input           rgmii_rx_clk    ,// rgmii的读取时钟，由PHY芯片提供
    input   [3:0]   rgmii_rx_data   ,// rgmii的接受数据，由PHY芯片提供
    input           rgmii_rx_ctl    ,// rgmii的数据控制信号，由PHY芯片提供

    // 处理RGMII信号，转为gmii信号供FPGA的后续处理
    output          gmii_rx_clk     ,// gmii的读取时钟，由PHY芯片提供，转为BUFG后供FPGA使用
    output          gmii_rx_en      ,// gmii的读取有效信号
    output  [7:0]   gmii_rx_data     // gmii的接收数据读取
);

// wire define
wire [1:0]  gmii_rx_en_t        ;   // 两位gmii接收有效信号

//**********************************************
//**            main code
//**********************************************

// 减少时钟延时（但会增加功耗）

assign gmii_rx_clk = rgmii_rx_clk;
assign gmii_rx_en  = gmii_rx_en_t[0] & gmii_rx_en_t[1];   // 当gmii_rx_en为1'd1时，接受数据有效

// IDDR用于双沿输入数据的输出
IDDR #(
    .DDR_CLK_EDGE   ("SAME_EDGE_PIPELINED"  ),  // "OPPOSITE_EDGE", "SAME_EDGE"
                                                // or "SAME_EDGE_PIPELINED"
    .INIT_Q1        (1'b0                   ),  // Initial value of Q1: 1'b0 or 1'b1
    .INIT_Q2        (1'b0                   ),  // Initial value of Q2: 1'b0 or 1'b1
    .SRTYPE         ("SYNC"                 )   // Set/Reset type: "SYNC" or "ASYNC"
) u_iddr_rx_ctl (
    .Q1             (gmii_rx_en_t[0]        ),  // 1-bit output for positive edge of clock
    .Q2             (gmii_rx_en_t[1]        ),  // 1-bit output for negative edge of clock
    .C              (rgmii_rx_clk      ),  // 1-bit clock input
    .CE             (1'b1                   ),  // 1-bit clock enable input
    .D              (rgmii_rx_ctl           ),  // 1-bit DDR data input
    .R              (1'b0                   ),  // 1-bit reset
    .S              (1'b0                   )   // 1-bit set
);

// 对rgmii_data_rx进行处理
genvar i;
generate for (i=0; i<4; i=i+1)
    begin : rxdata_bus
        // IDDR用于双沿输入数据的输出
        IDDR #(
            .DDR_CLK_EDGE   ("SAME_EDGE_PIPELINED"  ),  // "OPPOSITE_EDGE", "SAME_EDGE"
                                                        // or "SAME_EDGE_PIPELINED"
            .INIT_Q1        (1'b0                   ),  // Initial value of Q1: 1'b0 or 1'b1
            .INIT_Q2        (1'b0                   ),  // Initial value of Q2: 1'b0 or 1'b1
            .SRTYPE         ("SYNC"                 )   // Set/Reset type: "SYNC" or "ASYNC"
        ) u_iddr_rxd (
            .Q1             (gmii_rx_data[i]        ),  // 1-bit output for positive edge of clock
            .Q2             (gmii_rx_data[4+i]      ),  // 1-bit output for negative edge of clock
            .C              (rgmii_rx_clk      ),  // 1-bit clock input
            .CE             (1'b1                   ),  // 1-bit clock enable input
            .D              (rgmii_rx_data[i]       ),  // 1-bit DDR data input
            .R              (1'b0                   ),  // 1-bit reset
            .S              (1'b0                   )   // 1-bit set
        );
    end
endgenerate

endmodule
